package com.hw.backapi.context;


import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.PutObjectResult;
import com.amazonaws.services.s3.model.S3Object;
import com.hw.common.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

/**
 * aws oss 亚马逊
 */
@Component
@Slf4j
public class AwsOssContext {
    @Value("${s3.fileBucket}")
    private String ossBucketName;

    @Value("${s3.accessKey}")
    private String accessKey;

    @Value("${s3.secretKey}")
    private String secretKey;

    @Value("${s3.region}")
    private String region;

    public AmazonS3 ossClient = null;

    public AmazonS3 getOssClient(){
        if (ossClient == null) {
            AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
            AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCredentials));
            //设置S3的地区
            builder.setRegion(region);
            return builder.build();
        }
        return ossClient;
    }

    /**
     * 上传文件到oss
     * @param file
     * @param sourceFile
     * @return
     */
    public String uploadOssFile(String file, InputStream sourceFile) {
        String descFile = file;
        try {
            String contentType = getContentType(file);

            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentType(contentType);
            objectMetadata.setContentLength(Long.valueOf(sourceFile.available()));
            PutObjectRequest putObjectRequest = new PutObjectRequest(getOssBucketName(), descFile, sourceFile,
                    objectMetadata);
            PutObjectResult putObjectResult = getOssClient().putObject(putObjectRequest);
            log.info("文件上传OSS成功！");

            return file;
        } catch (Exception e) {
//            e.printStackTrace();
            descFile = "";
            log.error("文件上传OSS错误。");
        }
        return descFile;
    }


    /**
     * @descrition 下载文件
     * @author lipeng
     * @param fileName
     * @param outputFileName
     * @param response 
     * @return void
     */
    public void downloadFile(String fileName , String outputFileName, HttpServletResponse  response){
        BufferedInputStream input = null;
        OutputStream outputStream = null;

        // 创建OSSClient实例。
        try {
            S3Object ossObject = getOssClient().getObject(new GetObjectRequest(getOssBucketName(), fileName));
            response.reset();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/x-msdownload");
            response.addHeader("Content-Disposition",
                    "attachment;filename=" + new String(outputFileName.getBytes("gb2312"), "ISO8859-1"));

            input = new BufferedInputStream(ossObject.getObjectContent());
            byte[] buffBytes = new byte[1024];
            outputStream = response.getOutputStream();
            int read = 0;
            while ((read = input.read(buffBytes)) != -1) {
                outputStream.write(buffBytes, 0, read);
            }
            outputStream.flush();
            // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
            ossObject.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new BaseException("Error Code: NoSuchKey");
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (input != null) {
                    input.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    @PreDestroy
    public void detory() {
        getOssClient().shutdown();
        System.out.println("detory");
    }

    /**
     * 返回文件的MIME类型
     *
     * @param FilenameExtension
     * @return String
     */
    private String getContentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        if (FilenameExtension.equalsIgnoreCase(".mp4")) {
            return "video/mp4";
        }
        if (FilenameExtension.equalsIgnoreCase(".mp3")) {
            return "audio/mpeg";
        }
        return null;
    }



    public String getOssBucketName() {
        return ossBucketName;
    }
}
